package com.bckj.fastboot.core.extra.dbsearch;

import com.bckj.fastboot.core.extra.dbsearch.dbmodel.DbModelFactory;
import com.bckj.fastboot.core.extra.dbsearch.dbmodel.DbModelInfo;
import com.bckj.fastboot.core.extra.dbsearch.dbview.DbView;
import com.bckj.fastboot.core.extra.dbsearch.model.DbSearchRequest;
import com.bckj.fastboot.core.extra.dbsearch.model.SearchItem;
import com.bckj.fastboot.core.mybatisplus.mapper.CommFastMapper;
import com.bckj.fastboot.core.sql.ConditionBuilder;
import com.bckj.fastboot.core.sql.StatementBuilder;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;

import java.util.List;

@RequiredArgsConstructor
public class DbSearcher {

    @Resource
    private CommFastMapper commFastMapper;

    public <T> List<T> search(DbView dbView, DbSearchRequest request, Class<T> clazz) {
        StatementBuilder statementBuilder = StatementBuilder.create();
        statementBuilder.select(dbView.getColumns());
        statementBuilder.from(dbView.getTables());
        buildWhere(statementBuilder, request.getWhere(), clazz);
        return commFastMapper.selectBySql(statementBuilder, clazz);
    }

    private void buildWhere(ConditionBuilder<?> co, List<SearchItem> where, Class<?> clazz) {
        for (SearchItem item : where) {
            if (item.getOp() == null || item.getOp().isBlank()) {
                co.where(getColumn(item.getName(), clazz), item.getValue(), " = ");
            } else if (item.getOp().equals("and")) {
                co.and(op -> buildWhere(op, item.getChildren(), clazz));
            } else if (item.getOp().equals("or")) {
                co.or();
            } else if (item.getOp().equals("like")) {
                co.like(getColumn(item.getName(), clazz), item.getValue());
            } else if (item.getOp().equals("in")) {
                co.in(getColumn(item.getName(), clazz), item.getValues());
            } else if (item.getOp().equals("between")) {
                co.between(getColumn(item.getName(), clazz), item.getLeftValue(), item.getRightValue());
            } else {
                throw new RuntimeException("不支持的操作 " + item.getOp());
            }
        }
    }

    private String getColumn(String name, Class<?> clazz) {
        DbModelInfo modelInfo = DbModelFactory.getDbModelInfo(clazz);
        if (modelInfo != null) {
            return modelInfo.getColumn(name);
        }
        return name;
    }
}
